package com.company;

import java.lang.reflect.Constructor;

public class ActionConstructor {
    public static void main(String[] args) throws Exception {
        //1.  获取类的class对象
        Class cls = Person.class;

        //2. 通过 class 对象获取类的空参构造器，和有参构造器

        //2.1 获取 public 修饰的空参构造器
//        Constructor ctr1 = cls.getConstructor();
//
//        // 2.1.1使用 空参构造器创建对象
//        Object person1 = ctr1.newInstance();
//        System.out.println(person1);  //name = null     age = 0


        // 2.2 获取 public 修饰的 有参构造器
//        Constructor ctr2 = cls.getConstructor(String.class, int.class);
//        // 2.2.1使用 有参构造器创建对象
//        Object person2 = ctr2.newInstance("张三", 22);
//        System.out.println(person2);  // name = 张三     age = 22

        System.out.println("一次性获取所有Public 修饰的 构造方法");
        // 2.3 一次性获取所有的 public 修饰的 构造函数
         Constructor[] ctrArr = cls.getConstructors();
         for(Constructor ctr_ele: ctrArr){
             System.out.println(ctr_ele);
             /*
                public com.company.Person()
                public com.company.Person(java.lang.String,int)
              */
         }

         // 2.4 获取 任意权限修饰符修饰的 空参构造方法
         Constructor ctr3 = cls.getDeclaredConstructor();
        ctr3.setAccessible(true);  // 忽略访问权限修饰符的检查，使用 private 修饰的 都要将 setAccessible 设置为 true

        //2.4.1 使用 空参构造器创建对象
         Object person3 = ctr3.newInstance();
        System.out.println(person3);  //name = null     age = 0

        // 2.5 获取 任意权限修饰符修饰的 有参构造方法
        Constructor ctr4 = cls.getDeclaredConstructor(String.class, int.class);
        ctr4.setAccessible(true);  // 忽略访问权限修饰符的检查，使用 private 修饰的 都要将 setAccessible 设置为 true
        Object person4 = ctr4.newInstance("李四", 33);
//        Object person4 = ctr4.newInstance();
        System.out.println(person4);  //name = 李四     age = 33


        //
        System.out.println("获取所有的构造方法");
        Constructor[] ctrDeclareArr = cls.getDeclaredConstructors();

        for (Constructor ctr_ele: ctrDeclareArr){
            System.out.println(ctr_ele);
        }

        // 直接使用 类的对象 调用 newInstance方法 创建对象
        System.out.println(cls.newInstance());  //name = null     age = 0






    }
}

/*
default (即默认，什么也不写）: 在同一包内可见，不使用任何修饰符。使用对象：类、接口、变量、方法。

private : 在同一类内可见。使用对象：变量、方法。 注意：不能修饰类（外部类）

public : 对所有类可见。使用对象：类、接口、变量、方法

protected : 对同一包内的类和所有子类可见。使用对象：变量、方法。 注意：不能修饰类（外部类）。
 */